﻿/* Copyright (c) 2010 Lexalytics Inc.

 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation
 files (the "Software"), to deal in the Software without
 restriction, including without limitation the rights to use,
 copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following
 conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

// Needed for Office and Excel integration
using Excel = Microsoft.Office.Interop.Excel;

namespace Lexalytics4Excel.Dialogs
{
    /// <summary>
    /// Dialog displayed to gather information on user range selection
    /// </summary>
    public partial class SelectData : Form
    {
        // Private member variables
        private Excel.Range _SelectedDataRange;
        private int _TextColumnIndex = 1;

        /// <summary>
        /// Property to capture user specification if data range selected has header row
        /// </summary>
        public bool SelectedDataHasHeader
        {
            get { return MultiRowHeaderCheckbox.Checked; }
        }
        /// <summary>
        /// Property to capture user specification of column containing text 
        /// </summary>
        public int TextColumnIndex
        {
            get { return _TextColumnIndex; }
        }

        /// <summary>
        /// Dialog constructor
        /// </summary>
        /// <param name="DataRange">Row and Column range selected by user</param>
        public SelectData(Excel.Range DataRange)
        {
            InitializeComponent();
            _SelectedDataRange = DataRange;
        }

        /// <summary>
        /// Event handler for dialog load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectData_Load(object sender, EventArgs e)
        {
            try
            {
                // Enable or disable multi-row description and checkbox
                MultiRowDescription.Enabled = (_SelectedDataRange.Rows.Count > 1);
                MultiRowHeaderCheckbox.Enabled = (_SelectedDataRange.Rows.Count > 1);

                // Enable or disable multi-column description and checkbox
                MultiColumnDescription.Enabled = (_SelectedDataRange.Columns.Count > 1);
                MultiColumnTextSelector.Enabled = (_SelectedDataRange.Columns.Count > 1);

                // Default MultiRowHeaderCheckbox to checked if first row of sheet is included
                string strRange_R1C1 = _SelectedDataRange.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlR1C1, Type.Missing, Type.Missing);
                string[] arrBounds = strRange_R1C1.Split(new char[] { 'R', 'C', ':' }, StringSplitOptions.RemoveEmptyEntries);
                if (arrBounds[0] == "1")
                    MultiRowHeaderCheckbox.Checked = true;
                else
                    MultiRowHeaderCheckbox.Checked = false;

                // Set up contents in Text column selector dropdown
                if (MultiColumnTextSelector.Enabled)
                {
                    LoadColumnSelector();
                    MultiColumnTextSelector.SelectedIndex = _TextColumnIndex - 1;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show("There was a problem evaluating the selected data.\n" + err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                OkButton.Enabled = false;
            }
        }

        /// <summary>
        /// Event handler for "My data has headers" checkbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MultiRowHeaderCheckbox_CheckedChanged(object sender, EventArgs e)
        {
            LoadColumnSelector();
        }

        /// <summary>
        /// Event handler for "Select text column" combobox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MultiColumnTextSelector_SelectedIndexChanged(object sender, EventArgs e)
        {
            _TextColumnIndex = MultiColumnTextSelector.SelectedIndex + 1;
        }


        /// <summary>
        /// Loads combobox for selecting the column of text content with column names or
        /// header text if indicated by user.
        /// </summary>
        private void LoadColumnSelector()
        {
            string sColHeader = "";

            try
            {
                MultiColumnTextSelector.Items.Clear();

                // Determine number of columns
                int nMinCol = 1;
                int nMaxCol = 1;
                string strRange_R1C1 = _SelectedDataRange.get_Address(1, Type.Missing, Excel.XlReferenceStyle.xlR1C1, Type.Missing, Type.Missing);
                string[] arrBounds = strRange_R1C1.Split(new char[] { 'R', 'C', ':' }, StringSplitOptions.RemoveEmptyEntries);
                switch (arrBounds.GetLength(0))
                {
                    case 2:
                        nMinCol = Convert.ToInt32(arrBounds[0]);
                        nMaxCol = Convert.ToInt32(arrBounds[1]);
                        break;
                    case 4:
                        nMinCol = Convert.ToInt32(arrBounds[1]);
                        nMaxCol = Convert.ToInt32(arrBounds[3]);
                        break;
                    default:
                        nMaxCol = _SelectedDataRange.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing).Column;
                        break;
                }

                for (int nColIndex = nMinCol; nColIndex <= nMaxCol; nColIndex++)
                {
                    if (MultiRowHeaderCheckbox.Checked)
                    {
                        Excel.Range rHeader = (Excel.Range)_SelectedDataRange.Cells[1, nColIndex];
                        if ((rHeader.Value2 != null) && (rHeader.Value2.ToString().Trim().Length>0))
                            sColHeader = rHeader.Value2.ToString();
                        else
                            sColHeader = String.Format("Column{0}",nColIndex);
                    }
                    else
                    {
                        Excel.Range rHeader = (Excel.Range)_SelectedDataRange.Cells[1, nColIndex];
                        sColHeader = String.Format("Column{0}", nColIndex);
                    }
                    MultiColumnTextSelector.Items.Add(sColHeader);
                }
                MultiColumnTextSelector.SelectedIndex = _TextColumnIndex - 1;
            }
            catch (Exception err)
            {
                MessageBox.Show("There was a problem evaluating the selected data.\n" + err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                OkButton.Enabled = false;
            }
        }

        /// <summary>
        /// Event handler for OK button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OkButton_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
            this.Close();
        }

    }
}
